﻿using System;
using Silver3D.Math;

namespace Silver3D.Graphics
{
    public class PerspectiveCamera : Camera
    {
        private double fov = 45.0 * Util.DegToRad;
        private double aspectRatio = 4.0 / 3.0;

        /// <summary>
        /// Gets or sets the vertical (y direction) field of view of this camera, in radians.
        /// </summary>
        public double FieldOfView
        {
            get { return fov; }
            set { fov = value; IsProjectionDirty = true; }
        }

        /// <summary>
        /// Gets or sets the vertical (y direction) field of view of this camera, in degrees.
        /// </summary>
        public double FieldOfViewDegrees
        {
            get { return fov * Util.RadToDeg; }
            set { FieldOfView = value * Util.DegToRad; }
        }

        /// <summary>
        /// Gets or sets the aspect ratio of this camera.
        /// The aspect ratio determines the horizontal field of view (x direction) by the equation
        /// ratio = width / height.
        /// </summary>
        public double AspectRatio
        {
            get { return aspectRatio; }
            set { aspectRatio = value == 0.0 ? 1.0 : value; IsProjectionDirty = true; }
        }

        public PerspectiveCamera(Scene scene, string id)
            : base(scene, id)
        {
        }

        protected override void UpdateProjection()
        {
            double f = 1.0 / System.Math.Tan(fov * 0.5);

            projection = new Matrix44(
                f / aspectRatio, 0.0, 0.0, 0.0,
                0.0, f, 0.0, 0.0,
                0.0, 0.0, (ZFar + ZNear) / (ZNear - ZFar),  2.0 * ZFar * ZNear / (ZNear - ZFar),
                0.0, 0.0, -1.0, 0.0);
        }
    }
}
